using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;

namespace Konst3d.Efficiency
{
    public class SimpleBinaryEncoder : ICryptographicEngine
    {
        #region Constructor

        public SimpleBinaryEncoder(Encoding encoding)
        {
            Contract.Requires(encoding != null);
            Encoding = encoding;
        }

        #endregion // Constructor

        #region ICryptographicEngine Members

        public Encoding Encoding
        {
            get;
            private set;
        }

        public int GetLength(string text)
        {
            return Encoding.GetByteCount(text);
        }

        public byte[] Encode(string text)
        {
            byte[] data = null;

            if (!String.IsNullOrEmpty(text))
            {
                data = Encoding.GetBytes(text);
                EncodeBytes(data);
            }
            else
            {
                data = new byte[0];
            }

            return data;
        }

        public string Decode(byte[] data)
        {
            var localData = new byte[data.Length];

            Array.Copy(data, localData, data.Length);
            DecodeBytes(localData);

            return Encoding.GetString(localData);
        }

        public string Decode(byte[] data, int offset, int length)
        {
            var localData = new byte[length];

            Array.Copy(data, offset, localData, 0, length);
            DecodeBytes(localData);

            return Encoding.GetString(localData);
        }

        #endregion // ICryptographicEngine Members

        #region Overrides

        public override string ToString()
        {
            return "Binary inversion";
        }

        #endregion // Overrides

        #region Private Methods

        private void EncodeBytes(byte[] data)
        {
            for (int i = 0; i < data.Length; ++i)
            {
                data[i] = (byte)~data[i];
            }
        }

        private void DecodeBytes(byte[] data)
        {
            for (int i = 0; i < data.Length; ++i)
            {
                data[i] = (byte)~data[i];
            }
        }

        #endregion // Private Methods
    }
}
